//The purpose of this class is to allow the user to navigate through the application.
package com.mckillion.icare;

//Import the java classes required
import java.util.Timer;
import java.util.TimerTask;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.PendingIntent;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.pm.ActivityInfo;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.telephony.SmsManager;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.PopupWindow;
import android.widget.TextView;
import android.widget.Toast;
import com.mckillion.icare.R;

//The class extends activity which allows the Android features to be imported.
//On click listener extended to allow button activity to take place.
public class HomeScreen extends Activity implements View.OnClickListener{
	//Declare the variables required for this class.
	//private variables are used to promote consistency.
	private ImageButton helpButton, settingsButton, calenderButton, bikeButton,
						computerButton, basketButton, resetButton;
	private ImageView infoButton;
	private TextView contactName, contactNumber, infoText; //locText, motionText
	private String prefName, prefNum, provider, homeLat, homeLong, radius, inactiveMinText;
	private SharedPreferences prefs;
	private SmsManager smsManager;
	private long minNum;
	private AlertDialog alertDialog;
	private static String PROXIMITY_ALERT = "com.mckillion.icare.gps.ProximityIntentReciever";
	private boolean locationStatus, activityStatus, movement, messageSent, timerStatus;
	protected static boolean messageSent2 = false; //Protected as value is passed to another class.
	private LocationManager locationManager;
	private Location location;
	private Timer timer;
	private TimerTask smsTimerTask;
	
	//overwrite the onCreate method so that variables are instantiated on opening.
	public void onCreate(Bundle savedInstanceState) {
	        //Call to the super class.
			super.onCreate(savedInstanceState);
	        
			//Ensure that the application remains in portrait mode.
			this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
			
			//Set the content layout to the main_screen XML file.
	        setContentView(R.layout.doctor_office);
	      
	    	//make the objects match the objects in the layout file.
	        contactName = (TextView)findViewById(R.id.pri_name);
	        contactNumber = (TextView)findViewById(R.id.pri_num);
	        
	        //Create the SMSManager with default settings.
	        smsManager = SmsManager.getDefault();
	        
	        //Create the PreferenceManager with default settings.
	        prefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
	        
	        //Set the strings in this activity to match the strings saved in the preferences, if statements used in case the values equal null.
	    	prefName = prefs.getString("primary_name","Enter Name in Settings");
	    	if(prefName == "")
	    	{	prefName = "Enter Name in Settings";
	    	}	else
	    		{	contactName.setText(prefName);
	    		}
	    	
	    	prefNum = prefs.getString("primary_number","Enter Number in Settings");
	    	if(prefNum == "")
	    	{	prefNum = "Enter Number in Settings";
	    	}	else
	    		{	contactNumber.setText(prefNum);
	    		}
	    	
	    	//Find out from preferences if the location service is turned on.
	        locationStatus = prefs.getBoolean("locational_pref", true);
	        
	        //If the location service is enabled and GPS is turned on carry out the code.
	        if(locationStatus == true){
	        	//Create the LocationManager.
	            locationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
	            
	            System.out.println ("location service is on");
	            
	            //Set the location manager to use GPS
	        	provider = LocationManager.GPS_PROVIDER;
	        	
	        	//Get the last known location
	            location = locationManager.getLastKnownLocation(provider);
	            
	            //Send the location to the updateWithNewLocation method that I have created.
	            updateWithNewLocation(location);
	            
	            //Listen for changes in the location and apply the locationListener to take action.
	            locationManager.requestLocationUpdates(provider, 5000, 5, locationListener);
	            
	            //Create an intent and register the receiver to this. This will define the perimeter.
	            IntentFilter filter = new IntentFilter(PROXIMITY_ALERT);
	            registerReceiver(new ProximityIntentReciever(), filter);
	            
	            //set the proximity alert method which I have created below.
	            setProximityAlert();
	        }	
	        
	        //Set the inactivity measure to the same value in preferences.
	        inactiveMinText = prefs.getString("inactivity_length", "0");
	        
	        if(inactiveMinText == "")
	        {	inactiveMinText = "1400"; //Set the default to 24 hours if null is entered.
		        SharedPreferences.Editor editor = prefs.edit();
		        editor.putString("inactivity_length", inactiveMinText);
		        editor.commit();
	        }
	        
	        //Set the minNum long to the same value in preferences.
	        minNum = Long.valueOf(inactiveMinText);
	        
	        //Determine if activity alerts are turned on.
	        activityStatus = prefs.getBoolean("inactivity_pref", true);
	        
	        //If the activity monitor is turned on create a SensorManager and SensorListener which monitors accelerometer activity.
	        if(activityStatus == true){
	        	SensorManager sensorManager = (SensorManager)getSystemService(Context.SENSOR_SERVICE);
	        	int sensorType = Sensor.TYPE_ACCELEROMETER;
	        	
	        	//Register a listener to the manager which will send a text if the sensor is inactive.
	        	sensorManager.registerListener(sensorListener, sensorManager.getDefaultSensor(sensorType), SensorManager.SENSOR_DELAY_NORMAL);
	        }
	    	
	    	//make the objects match the objects in the layout file.
	    	helpButton=(ImageButton)findViewById(R.id.help_button);
	    	settingsButton=(ImageButton)findViewById(R.id.settings_button);
	    	calenderButton=(ImageButton)findViewById(R.id.calender_button);
	    	bikeButton=(ImageButton)findViewById(R.id.bike_button);
	    	computerButton=(ImageButton)findViewById(R.id.computer_button);
	    	basketButton=(ImageButton)findViewById(R.id.basket_button);
	    	resetButton=(ImageButton)findViewById(R.id.reset_button);
	    	infoButton=(ImageView)findViewById(R.id.imageView4);
		    	    	
	    	//Set a listener for the information button
	        infoButton.setOnClickListener(new OnClickListener() {
				public void onClick(View v) {
					//Use a layout inflater to open a pop-up window with the informational text.
					LayoutInflater layoutInflater = (LayoutInflater)getBaseContext().getSystemService(LAYOUT_INFLATER_SERVICE);  
					View popupView = layoutInflater.inflate(R.layout.info_popup, null);  
				    final PopupWindow popupWindow = new PopupWindow(popupView, LayoutParams.WRAP_CONTENT,  LayoutParams.WRAP_CONTENT);
				    
				    infoText = (TextView) popupWindow.getContentView().findViewById(R.id.info_text);
				    infoText.setText("This is the home page of the iCare application." + "\n" + "\n" +
				    					"Use the image buttons to navigate through the application." + "\n" + "\n" +
				    					"The reset button restores the default settings. The panic button will send " +
				    					"an alert to the emergency contact and the settings button allows the preferences to " +
				    					"be changed." + "\n" + "\n" + "Press dismiss to close this message.");
				    
				    //create a dismiss button to close the pop-up window.
				    Button dismiss = (Button)popupView.findViewById(R.id.dismiss_button);
		            dismiss.setOnClickListener(new Button.OnClickListener(){
		            	@Override
		            	public void onClick(View v) {
		            		popupWindow.dismiss();
		            	}});
		               
		            //Put the pop-up window in the centre of the screen
		            popupWindow.showAtLocation(infoButton, Gravity.CENTER, 0, 0);
		   }});
	    	
	        //Set a listener for the reset button.
	        resetButton.setOnClickListener(new Button.OnClickListener(){
	    	    @SuppressWarnings("deprecation")
				public void onClick(View arg0) {
	    	    	//When the reset button is pressed an alert dialogue will be shown as this has a big impact on the application.
	    	    	alertDialog = new AlertDialog.Builder(HomeScreen.this).create();
	    	    	
	    	    	//Set the title and the message that accompany the alert
	    	    	alertDialog.setTitle("Reset default preferences?");
	    	    	alertDialog.setMessage("Are you sure?");
	    	    	
	    	    	//set the button so the user needs to confirm the reset.
	    	    	alertDialog.setButton("Yes", new DialogInterface.OnClickListener() {
	    	    	      public void onClick(DialogInterface dialog, int which) {
	    	    	    	  	// When yes is clicked the reset button will remove all of the stored preferences
	    	  	    			SharedPreferences.Editor editor = prefs.edit();
	    	  	    			editor.clear();
	    	  	    			editor.commit();
	    	                  
	    	  	    			//Show a toast notification to notify the user of this.
	    	  	    			Context context = getApplicationContext();
	    	         		    CharSequence text = "Settings and Preferences have been reset to default";
	    	         		    int duration = Toast.LENGTH_LONG;
	    	         		    Toast toast = Toast.makeText(context, text, duration);
	    	         		    toast.show();
	    	                  
	    	         		    //finish the current activities and start a new intent which restarts MainScreen with default values.
	    	         		    finish();
	    	         		    Intent i = new Intent();
	    	         		    i.setClassName("com.mckillion.icare", "com.mckillion.icare.MainScreen");
	    	         		    startActivity(i); //start the intent.
	    	    	    }});
	    	    	
	    	    		alertDialog.show();
	    	    	}});
	    	
	        //Set a listener for the panic button
	    	helpButton.setOnClickListener(new Button.OnClickListener(){
		    public void onClick(View arg0) {
		    	 //Send a text message to the primary contact when the button is pressed.
		    	
		    	 //Get the number from the preferences, contactNumber retrieves this in line 105.
			     String smsNumber = contactNumber.getText().toString();
			     
			     //Set the text to be sent via SMS.
			     String smsText = "ALERT! The Panic Button has been pressed in iCare. Please Attempt to contact the user.";
			     
			     //Send the text using the smsManager.
			     smsManager.sendTextMessage(smsNumber, null, smsText, null, null);
			     
			     //Show a toast notification to inform the user a test has been sent
			     Context context = getApplicationContext();
			     CharSequence text = "Alert Message Sent to Primary Contact";
			     int duration = Toast.LENGTH_LONG;
			     Toast toast = Toast.makeText(context, text, duration);
			     toast.show();
		    }}); 
	        
	        //Set a listener for the settings button which starts the Settings class
	        settingsButton.setOnClickListener(new OnClickListener() {
				public void onClick(View v) {
					Intent i = new Intent(HomeScreen.this, Settings.class);
					startActivity(i);
				}
			});
	        
	        //Set a listener for the calendar button which starts the CalendarScreen class
	        calenderButton.setOnClickListener(new OnClickListener() {
				public void onClick(View v) {
					//Provide feedback when the button is pressed.
					calenderButton.setBackgroundResource(R.drawable.buttonpressed);
					
					Intent i = new Intent(HomeScreen.this, CalenderScreen.class);
					startActivity(i);
				}
			});
	        
	        //Set a listener for the bike button which starts the ExerciseScreen class
	        bikeButton.setOnClickListener(new OnClickListener() {
				public void onClick(View v) {
					//Provide feedback when the button is pressed.
					bikeButton.setBackgroundResource(R.drawable.buttonpressed);
					
					Intent i = new Intent(HomeScreen.this, ExerciseScreen.class);
					startActivity(i);
				}
			});
	        
	        //Set a listener for the computer button which starts the ComputerScreen class
	        computerButton.setOnClickListener(new OnClickListener() {
				public void onClick(View v) {
					//Provide feedback when the button is pressed.
					computerButton.setBackgroundResource(R.drawable.buttonpressed);
					
					Intent i = new Intent(HomeScreen.this, ComputerScreen.class);
					startActivity(i);
				}
			});
	        
	        //Set a listener for the basket button which starts the IntakeScreen class
	        basketButton.setOnClickListener(new OnClickListener() {
				public void onClick(View v) {
					//Provide feedback when the button is pressed.
					basketButton.setBackgroundResource(R.drawable.buttonpressed);
					
					Intent i = new Intent(HomeScreen.this, IntakeScreen.class);
					startActivity(i);
				}
			});
	}
	
	//Create the locationListener which is used in onCreate
    LocationListener locationListener = new LocationListener(){
    	
		public void onLocationChanged(Location location) {
			//When location is changed run the updateWithNewLocation method, shown below.
			updateWithNewLocation(location);
		}
		public void onProviderDisabled(String provider) {/*not used*/}
		public void onProviderEnabled(String provider) {/*not used*/}
		public void onStatusChanged(String provider, int status, Bundle extras) {/*not used*/}
    };
    
    private void updateWithNewLocation(Location location){  	
    	//Unused however was used for testing as shown.
    	/*If location is not equal to null set the text in the onCreate method to the current coordinates. 
    	if(location != null){
    		double lat = location.getLatitude();
    		double lng = location.getLongitude();
    		
    		//Show the values on the main screen  		
    		locText.setText("Lat: " + lat + "\nLong: " + lng);
    	}*/
    }
    
    //create the proximity alert which will be used to create a proximity alert. The proximity alert will send the text.
    private void setProximityAlert(){
    	//Create the objects to be used within the proximity alert.
    	String locService = Context.LOCATION_SERVICE;
    	LocationManager locManager;
    	locManager = (LocationManager)getSystemService(locService);
    	
    	//get the locational values from preferences.
    	homeLat = prefs.getString("home_lat_pref","0");
    	homeLong = prefs.getString("home_long_pref","0");
    	radius = prefs.getString("fence_range","1000");
    	
    	//assign the strings from preferences to values that the proximity alert will accept.
    	double lat = Double.valueOf(homeLat);
    	double lng = Double.valueOf(homeLong);
    	float rad = Float.valueOf(radius);
    	long expiration = -1; //-1 shows that the expiration value will not be used.
    	
    	//Create a new intent with the PROXIMITY ALERT string.
    	Intent intent = new Intent(PROXIMITY_ALERT);
    	
    	//Create a PendingIntent and return the broadcast to be used within the proximity alert.
    	PendingIntent proximityIntent = PendingIntent.getBroadcast(this, -1, intent, 0);
    	
    	//Add the proximity alert to the location manager. This takes the latitude, longitude and radius from preferences
    	//It also adds the PendingIntent (proximityIntent) which will send a text if the radius is broken
    	locManager.addProximityAlert(lat, lng, rad, expiration, proximityIntent);
    }
        
    	//Create the sensor listener used in the onCreate method.
		SensorEventListener sensorListener = new SensorEventListener(){
   	
		public void onSensorChanged(SensorEvent event)
		{	//when the sensor has been moved call the updateWithNewSensorVal method.	
			updateWithNewSensorVal(event);
		}

		public void onAccuracyChanged(Sensor sensor, int accuracy) {/*not used*/}};
	    
	    //Create the updateWithNewSensorVal method.
	    private void updateWithNewSensorVal(SensorEvent sensorVal)
	    {  	//Add the sensor values to the main screen to show movement.
	    	//motionText.setText("X: " + sensorVal.values[0] + "\nY: " + sensorVal.values[1] + "\nZ: " + sensorVal.values[2]);
	    	
	    	//Create an algorithm to determine what movement is
	    	double accMag = (sensorVal.values[0]*sensorVal.values[0]) + (sensorVal.values[1]*sensorVal.values[1]) + (sensorVal.values[2]*sensorVal.values[2]);
			double mag = Math.sqrt(accMag);
			
			//The resting magnitude of my device is 9.8 therefore any difference + or - 1 will count as movement.
			if(mag <= 8.8 || mag >= 10.8){
				//if movement is detected cancel the timer and timerTask and change the timerStatus and movement states.
				movement = true;
				timer.cancel(); 
				smsTimerTask.cancel();
				timerStatus = false;
				System.out.println("Phone is moving"); //used to show functionality on screen (TESTING)
			}	
			
			else	
			{	movement = false; //movement is not detected if the "mag" parameters above are not met.
				System.out.println("Phone is NOT moving"); //used to show functionality on screen (TESTING)
					
				//Create the TimerTask that will send the text message when the timer finishes. 
				smsTimerTask = new TimerTask(){	
					@Override
					public void run() 
					{	if(messageSent == false)
						{	//If a text has not been sent send it, same way as in the onCreate
						    
							String smsNumber = contactNumber.getText().toString();
						    String smsText = "ALERT! The phone in iCare has been inactive for the set time.";
						    smsManager.sendTextMessage(smsNumber, null, smsText, null, null);
						    
						    System.out.println("TEXT MESSAGE SENT DUE TO INACTIVITY"); //used to show functionality
						    
						    //Change the message state to true to avoid multiple texts.
						    messageSent = true;
						}	
					}
				};	
				
				if(movement == false && timerStatus == false)
				{	//if the timer is not running and the device is not moving create and start a timer.
					timer = new Timer();
					timer.schedule(smsTimerTask, (minNum*1000*60));
					timerStatus = true;
					System.out.println("New Timer CREATED"); //used to show functionality
				}
			}
	    }
	    	
	@Override
	public boolean onCreateOptionsMenu(Menu menu) 
	{	//inflate the android option_menu from XML layout
		MenuInflater inflater = getMenuInflater();
	    inflater.inflate(R.menu.option_menu, menu);
	    return true;
	}
	
	public void goHome(){
		//Create a method to handle a button press on the menu
		Intent i = new Intent(this, HomeScreen.class);
		startActivity(i);
	}
	
	public void showSettings(){
		//Create a method to handle a button press on the menu
		Intent i = new Intent(this, Settings.class);
		startActivity(i);
	}
	
	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
	    // Handle item selection
	    switch (item.getItemId()) {
	        case R.id.menu_home:
	            goHome(); //if home button is pressed call the goHome method
	            return true;
	        case R.id.menu_settings:
	            showSettings(); //if settings button is pressed call the goHome method
	            return true;
	        default:
	            return super.onOptionsItemSelected(item);
	    }
	}
	
	@Override
	public void onBackPressed() {
		//handle the back button being pressed to ensure activities are not running simultaneously
		Intent setIntent = new Intent(Intent.ACTION_MAIN);
		setIntent.addCategory(Intent.CATEGORY_HOME);
		setIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
		startActivity(setIntent);
	}

	@Override
	public void onClick(View arg0) {
		// TODO Auto-generated method stub
	}
}
